#!/usr/bin/python
# -*- coding: UTF-8 -*-
#
# Created by Admin on 2024/7/11
# All rights reserved.
#
import json

import ddddocr
from fontTools.pens.svgPathPen import SVGPathPen
import matplotlib.pyplot as plt
import matplotlib.patches as patches
from matplotlib.path import Path
import matplotlib._color_data as mcd
from fontTools.ttLib import TTFont


def save_ttf_to_pic(font: TTFont, glyphset_key: str):
    # 获取包含字形名称和字形对象的--字形集对象glyphset
    glyphset = font.getGlyphSet()
    # 获取pen的基类
    pen = SVGPathPen(glyphset)
    # 查找对应glyphset_key的字形对象
    glyph = glyphset[glyphset_key]
    # 绘制对应glyphset_key的字形对象
    glyph.draw(pen)
    # 提取对应glyphset_key的绘制语句
    commands = pen._commands
    # 将绘制命令按照轮廓线划分
    total_commands = []
    command = []
    for i in commands:
        # 每一个命令语句
        if i == 'Z':
            # 以闭合路径指令Z区分不同轮廓线
            command.append(i)
            total_commands.append(command)
            command = []
        else:
            command.append(i)

    # 从'head'表中提取所有字形的边界框
    xMin = font['head'].xMin
    yMin = font['head'].yMin
    xMax = font['head'].xMax
    yMax = font['head'].yMax
    # print("所有字形的边界框: xMin = {}, xMax = {}, yMin = {}, yMax = {}".format(xMin, xMax, yMin, yMax))
    # 所有字形的边界框: xMin = -12, xMax = 264, yMin = -47, yMax = 220

    # 7.1.2 将TTF中的绘制命令转换成matplotlib可以看懂的命令语句
    # 笔的当前位置
    preX, preY = (0.0, 0.0)
    # 笔的起始位置
    startX, startY = (0.0, 0.0)
    # 所有轮廓点
    total_verts = []
    # 所有指令
    total_codes = []
    # 转换命令
    for i in total_commands:
        # 每一条轮廓线
        verts = []
        codes = []
        for command in i:
            # 每一条轮廓线中的每一个命令
            code = command[0]  # 第一个字符是指令
            vert = command[1:].split(' ')  # 其余字符是坐标点，以空格分隔
            # M = 路径起始 - 参数 - 起始点坐标 (x y)+
            if code == 'M':
                codes.append(Path.MOVETO)  # 转换指令
                verts.append((float(vert[0]), float(vert[1])))  # 提取x和y坐标
                # 保存笔的起始位置
                startX = float(vert[0])
                startY = float(vert[1])
                # 保存笔的当前位置(由于是起笔，所以当前位置就是起始位置)
                preX = float(vert[0])
                preY = float(vert[1])
            # Q = 绘制二次贝塞尔曲线 - 参数 - 曲线控制点和终点坐标(x1 y1 x y)+
            elif code == 'Q':
                codes.append(Path.CURVE3)  # 转换指令
                verts.append((float(vert[0]), float(vert[1])))  # 提取曲线控制点坐标
                codes.append(Path.CURVE3)  # 转换指令
                verts.append((float(vert[2]), float(vert[3])))  # 提取曲线终点坐标
                # 保存笔的当前位置--曲线终点坐标x和y
                preX = float(vert[2])
                preY = float(vert[3])
            # C = 绘制三次贝塞尔曲线 - 参数 - 曲线控制点1，控制点2和终点坐标(x1 y1 x2 y2 x y)+
            elif code == 'C':
                codes.append(Path.CURVE4)  # 转换指令
                verts.append((float(vert[0]), float(vert[1])))  # 提取曲线控制点1坐标
                codes.append(Path.CURVE4)  # 转换指令
                verts.append((float(vert[2]), float(vert[3])))  # 提取曲线控制点2坐标
                codes.append(Path.CURVE4)  # 转换指令
                verts.append((float(vert[4]), float(vert[5])))  # 提取曲线终点坐标
                # 保存笔的当前位置--曲线终点坐标x和y
                preX = float(vert[4])
                preY = float(vert[5])
            # L = 绘制直线 - 参数 - 直线终点(x, y)+
            elif code == 'L':
                codes.append(Path.LINETO)  # 转换指令
                verts.append((float(vert[0]), float(vert[1])))  # 提取直线终点坐标
                # 保存笔的当前位置--直线终点坐标x和y
                preX = float(vert[0])
                preY = float(vert[1])
            # V = 绘制垂直线 - 参数 - 直线y坐标 (y)+
            elif code == 'V':
                # 由于是垂直线，x坐标不变，提取y坐标
                x = preX
                y = float(vert[0])
                codes.append(Path.LINETO)  # 转换指令
                verts.append((x, y))  # 提取直线终点坐标
                # 保存笔的当前位置--直线终点坐标x和y
                preX = x
                preY = y
            # H = 绘制水平线 - 参数 - 直线x坐标 (x)+
            elif code == 'H':
                # 由于是水平线，y坐标不变，提取x坐标
                x = float(vert[0])
                y = preY
                codes.append(Path.LINETO)  # 转换指令
                verts.append((x, y))  # 提取直线终点坐标
                # 保存笔的当前位置--直线终点坐标x和y
                preX = x
                preY = y
            # Z = 路径结束，无参数
            elif code == 'Z':
                codes.append(Path.CLOSEPOLY)  # 转换指令
                verts.append((startX, startY))  # 终点坐标就是路径起点坐标
                # 保存笔的当前位置--起点坐标x和y
                preX = startX
                preY = startY
            # 有一些语句指令为空，当作直线处理
            else:
                codes.append(Path.LINETO)  # 转换指令
                verts.append((float(vert[0]), float(vert[1])))  # 提取直线终点坐标
                # 保存笔的当前位置--直线终点坐标x和y
                preX = float(vert[0])
                preY = float(vert[1])
        # 整合所有指令和坐标
        total_verts.append(verts)
        total_codes.append(codes)

    # 7.1.3 绘制PNG图片
    # 获取matplotklib中的颜色列表
    color_list = list(mcd.CSS4_COLORS)
    # 获取所有的轮廓坐标点
    total_x = []
    total_y = []
    for contour in total_verts:
        # 每一条轮廓曲线
        x = []
        y = []
        for i in contour:
            # 轮廓线上每一个点的坐标(x,y)
            x.append(i[0])
            y.append(i[1])
        total_x.append(x)
        total_y.append(y)
    # 创建画布窗口
    fig, ax = plt.subplots()
    # 按照'head'表中所有字形的边界框设定x和y轴上下限
    ax.set_xlim(xMin, xMax)
    ax.set_ylim(yMin, yMax)
    # 设置画布1:1显示
    ax.set_aspect(1)
    # 添加网格线
    # ax.grid(alpha=0.8, linestyle='--')
    # 画图
    for i in range(len(total_codes)):
        # (1)绘制轮廓线
        # 定义路径
        path = Path(total_verts[i], total_codes[i])
        # 创建形状，无填充，边缘线颜色为color_list中的颜色，边缘线宽度为2 随机颜色color_list[i + 10]
        patch = patches.PathPatch(path, facecolor='none', edgecolor=color_list[i + 10], lw=2)
        # patch = patches.PathPatch(path, facecolor='none', edgecolor='#000000', lw=2)
        # 将形状添到图中
        ax.add_patch(patch)
        # (2)绘制轮廓点--黑色,点大小为10
        # ax.scatter(total_x[i], total_y[i], color='black', s=10)
    # 隐藏plt的坐标轴
    plt.axis('off')
    # 保存图片
    plt.savefig(f"./temp.png")
    # 转字节
    with open(f"./temp.png", 'rb') as f:
        content = f.read()

    dddd = ddddocr.DdddOcr(show_ad=False)
    text = dddd.classification(content)
    return text


font = TTFont('read.ttf')
bestcmap = font['cmap'].getBestCmap()
print(bestcmap)
dict_ = {}
for i in bestcmap.keys():
    key_ = 'uni' + str(hex(i)).replace('0x', '').upper()
    origin_key = ('\\u' + str(hex(i)).replace('0x', '')).encode().decode('unicode-escape')
    #print(key_,origin_key)
    dict_[origin_key] = save_ttf_to_pic(font, key_)

print(json.dumps(dict_, ensure_ascii=False, indent=4))
# 将JSON字符串写入文件
with open('output.json', 'w', encoding='utf-8') as f:
    f.write(json.dumps(dict_, ensure_ascii=False, indent=4))